package com.example.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Slf4j
@Aspect
@Component
public class ExecutionAspect3 {

    /**
     * execution([修饰符] 返回值类型 [包名].类名.方法名(参数) [异常])
     * | 位置      | 示例                       | 说明                 |
     * | ---------| ------------------------- | -------------------- |
     * | 修饰符    | `public`（可省略）          | 方法访问控制修饰符   |
     * | 返回类型  | `*`，`void`，`String` 等   | `*` 表示任意返回类型 |
     * | 包名     | `com.example.service`     | 可用 `..` 匹配子包   |
     * | 类名     | `UserService`、`*Service` | `*` 支持通配         |
     * | 方法名   | `saveUser`、`*User`       | `*` 表示任意方法名   |
     * | 参数列表 | `()`、`(..)`、`(String)`  | `..` 表示任意参数    |
     */

    /**
     * | 运算符             | 说明
     * | `&&`              | 且
     * | `||`              | 或
     * | `!`               | 非
     */

    @Pointcut("execution(* com.example.service.impl.StudentServiceImpl.*(..))")
    public void callStudent() {
    }

    @Pointcut("execution(* com.example.service.impl.TeacherServiceImpl.*(..))")
    public void callTeacher() {
    }

    @Before("callStudent()")
    public void before() {
        log.info("before");
    }

    @After("callTeacher()")
    public void after() {
        log.info("after");
    }

    @Around("callStudent() || callTeacher()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        log.info("around before");
        Object proceed = proceedingJoinPoint.proceed();
        log.info("around after");
        return proceed;
    }

}
